﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using log4net;
using PowerGui.AddOn.Impl.Properties;
using PowerGui.AddOn.Interfaces;
using PowerGuiVsx.Core;
using Quest.PowerGUI.ScriptEditor.Shared;
using Quest.PowerGUI.ScriptEditor.Shared.Debugger;

namespace PowerGui.AddOn.Impl
{
    [PartCreationPolicy(CreationPolicy.Shared)]
    [Export(typeof(IPowerGui))]
    public class PowerGui : IPowerGui
    {
        private static bool initialized;
        private static readonly object Locker = new object();
        private readonly List<PsControlWrapper> _syntaxEditors;
        private static readonly ILog Log = LogManager.GetLogger(typeof (PowerGui));

        [Import]
        internal PowerShellDebugger InternalDebugger { get; set; }

        [Import]
        internal ConfigLoader ConfigLoader { get; set; }

        public Version SupportedVersion
        {
            get { return Version.Parse(Resources.SupportedVersion); }
        }

        public PowerGui()
        {
            _syntaxEditors = new List<PsControlWrapper>();
            //GetInstallPath();
        }

        public void Initialize()
        {
            if (initialized)
            {
                return;
            }

            lock (Locker)
            {
                try
                {
                    InstallPath = PowerGuiAssemblyLoader.InstallPath;
                    Installed = true;
                }
                catch (PowerGuiInstallationException)
                {
                    
                }

                //GetInstallPath();
                ConfigLoader.LoadSettings();

                var myDocuments = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

                var pgvsxProfile = Path.Combine(myDocuments, @"WindowsPowerShell\PowerGUIVSX.profile.ps1");

               // Debugger.SetVariable("PROFILE", pgvsxProfile);

                if (File.Exists(pgvsxProfile))
                {
                    //Debugger.Execute(pgvsxProfile);
                }
                
                InternalDebugger.Debugger.SwitchTabForDebugger += Debugger_SwitchTabForDebugger;
                initialized = true;
            }
        }

        PSSyntaxEditorControl Debugger_SwitchTabForDebugger(SelectFileArgs arg)
        {
        try
            {
            lock (Locker)
                {
                PsControlWrapper editor = _syntaxEditors.FirstOrDefault(m => string.Equals(m.Document.Filename, 
                    arg.FileName, StringComparison.CurrentCultureIgnoreCase));

                // PsControlWrapper cannot be created within this thread. It must have been created before.
                if (editor == null)
                    throw new Exception("Syntax editor hasn't been created");

                /*
                bool isNew = editor == null;
                if (isNew && arg.OpenIfNotExist)
                    {
                    editor = new PsControlWrapper(this, Debugger, Package);
                    editor.Document.LoadFile(arg.FileName);

                    editor.Disposed += SDisposed;
                    _syntaxEditors.Add(editor);
                    }
                 */
 
                return editor;
                }

            //foreach (var n in PowerShellDebugger.Notifies)
            //{
            //   n.ActivateEditor(editor, isNew);
            //}

            }
        catch (Exception ex)
            {
            Log.Error(ex.Message, ex);
            MessageBox.Show(ex.Message, "Error occurred", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return null;
            }
        }

        [Import]
        public Lazy<IConsole> Console
        {
            get; internal set;
        }

        public IScriptEditor CreateEditorInstance()
        {
            var s = new PsControlWrapper(this, InternalDebugger);
            s.Disposed += SDisposed;
            lock (Locker)
            {
                _syntaxEditors.Add(s);
            }
            return s;
        }


        public IScriptEditor CreateEditorInstance(string filename)
        {
            var s = new PsControlWrapper(this, InternalDebugger);
            s.Disposed += SDisposed;
            lock (Locker)
            {
                _syntaxEditors.Add(s);
            }

            s.LoadFile(filename);

            return s;
        }

        public IEnumerable<IScriptEditor> Editors
        {
            get
            {
                return _syntaxEditors;
            }
        }

        public bool Installed
        {
            get; private set;
        }

        public string InstallPath
        {
            get; private set;
        }

        public IDebugger Debugger
        {
            get
            {
                return InternalDebugger;
            }
        }

        void SDisposed(object sender, EventArgs e)
        {
            lock (Locker)
            {
                if (sender is PsControlWrapper)
                {
                    _syntaxEditors.Remove(sender as PsControlWrapper);
                }
            }
        }
    }
}
